from google.appengine.ext import db, webapp, blobstore
from google.appengine.ext.webapp import template, blobstore_handlers
from google.appengine.api import images
import logging
from src.util import *

# This demo app has used blobstore and datastore service. Please prefer the SDK:
#    - Datastore service: http://code.google.com/appengine/docs/python/datastore/overview.html
#    - Blobstore service: http://code.google.com/appengine/docs/python/blobstore/overview.html

def getImage():
    # Use only one instance of ImageModel in data store
    models = ImageModel.all().fetch(1)
    img = None
    if len(models) > 0:
        img = models[0]
        
    return img

class ImagesPage(webapp.RequestHandler):
    def get(self):        
        template_values = {
            'page': { 'title': 'Images' , 'name' : 'images' }
        }
        
        try:
            template_values['blobstore_upload_url'] = blobstore.create_upload_url('/images/blobstore')
        except:
            logging.warning("Can't use Blobstore service in demo of Image API")
        
        datastoreImage = getImage()
        if datastoreImage:           
            if datastoreImage.useBlobstore:
                template_values['keyType'] = 'blobstore'
                template_values['key'] = datastoreImage.blobKey
            else:
                template_values['key'] = datastoreImage.key().id()
                template_values['keyType'] = 'datastore'
        
        self.response.out.write(template.render(get_absolute_path('templates/images.htm'), template_values))


    def post(self):
        imageData = self.request.get('img')
        if imageData:
            # Use only one instance of ImageModel in data store
            img = getImage()
            if img:
                img.useBlobstore = False
                img.imageContent = db.Blob(imageData)
            else:      
                img = ImageModel(useBlobstore=False, imageContent=db.Blob(imageData))
                
            img.put()
        self.redirect('/images')


class ImagesProcessor(webapp.RequestHandler):
    def get(self):
        keyType = self.request.get('keyType')
        imageData = None
        img = None
        action = self.request.get('action')
        if keyType == 'datastore':
            imgModel = ImageModel.get_by_id(int(self.request.get('key')))
            img = images.Image(imgModel.imageContent)   
            if not action:
                imageData = imgModel.imageContent
        elif keyType == 'blobstore':
            img = images.Image(blob_key=self.request.get('key'))
            if not action:
                blob_reader = blobstore.BlobReader(self.request.get('key'))
                imageData = blob_reader.read()
                blob_reader.close()
        
        if action == 're':
            if keyType == 'blobstore':
                # Getting image's dimension from blob_key isn't supported so we have to hard-code the value here 
                newWidth = 200
                newHeight = 0
            else:
                newWidth = img.width / 3
                newHeight = img.height / 3
                
            img.resize(newWidth, newHeight)
        elif action == 'ro':
            img.rotate(int(self.request.get('param')))
        elif action == 'f':
            orientation = self.request.get('param')
            if orientation == 'h':
                img.horizontal_flip()
            else:
                img.vertical_flip()
        elif action == 'c':
            img.crop(0.25, 0.25, 0.75, 0.75)
        elif action == 'l':
            img.im_feeling_lucky()
            
        if not imageData:
            imageData = img.execute_transforms(images.JPEG)
            
        self.response.headers['Content-Type'] = 'image/jpeg'    
        self.response.out.write(imageData)


class ImageBlobUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        upload_files = self.get_uploads('img')
        if len(upload_files)>0:
            blobKey = str(upload_files[0].key())
            imageModel = getImage()
            if imageModel:
                imageModel.useBlobstore = True
                imageModel.blobKey = blobKey
            else:
                imageModel = ImageModel(useBlobstore=True, blobKey=blobKey)
            imageModel.put()
        self.redirect('/images')


class ImageModel(db.Model):
    imageContent = db.BlobProperty()
    blobKey = db.StringProperty()
    useBlobstore = db.BooleanProperty()
